/*
 * Created on 07.01.2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.jchains.receiver;

import java.io.File;
import java.util.Arrays;
import java.util.Properties;

import org.jchains.CORBA.PermissionTransferHelper;
import org.jchains.CORBA.PermissionTransferPackage.EnvironmentEntry;
import org.jchains.internal.Util;
import org.jchains.receiver.gui.GUIManagement;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Policy;
import org.omg.CosNaming.BindingIteratorHolder;
import org.omg.CosNaming.BindingListHolder;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.PortableServer.IdUniquenessPolicyValue;
import org.omg.PortableServer.LifespanPolicyValue;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.ThreadPolicyValue;

import com.sun.corba.se.impl.orbutil.CorbaResourceUtil;
import com.sun.corba.se.impl.orbutil.ORBConstants;
import com.sun.corba.se.spi.activation.*;
import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef;

abstract class ReceiverStrategy {
	
	abstract void init(String[] args);

	abstract Perm getPermission();

	abstract void end();
}

class FileReceiverStrategy extends ReceiverStrategy {
 
	GUIManagement gm;
	@Override
	void end() {
		// TODO Auto-generated method stub
		
	}

	@Override
	Perm getPermission() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	void init(String[] args) {
		// TODO Auto-generated method stub
		gm = new GUIManagement();
		gm.initGUI( Util.propsToEnvironmentEntry(System.getProperties()));
	}
	
}

class CORBAReceiverStrategy extends ReceiverStrategy {

	@Override
	void end() {
		// TODO Auto-generated method stub

	}

	@Override
	Perm getPermission() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	void init(String[] args) {
		Properties properties = System.getProperties();
		properties.put("org.omg.CORBA.ORBInitialHost", "localhost");
		properties.put("org.omg.CORBA.ORBInitialPort", "1050");

		try {
			// Step 1: Instantiate the ORB
			ORB orb = ORB.init(args, properties);

			// Step 2: Instantiate the servant
			PermissionTransferServant servant = new PermissionTransferServant(
					orb);

			// Step 3 : Create a POA with Persistent Policy
			// *******************
			// Step 3-1: Get the rootPOA
			POA rootPOA = POAHelper.narrow(orb
					.resolve_initial_references("RootPOA"));
			// Step 3-2: Create the Persistent Policy
			Policy[] persistentPolicy = new Policy[3];
			persistentPolicy[0] = rootPOA
					.create_lifespan_policy(LifespanPolicyValue.PERSISTENT);
			persistentPolicy[1] = rootPOA
					.create_id_uniqueness_policy(IdUniquenessPolicyValue.UNIQUE_ID);
			persistentPolicy[2] = rootPOA
			// .create_thread_policy(ThreadPolicyValue.SINGLE_THREAD_MODEL);
					.create_thread_policy(ThreadPolicyValue.ORB_CTRL_MODEL);
			// persistentPolicy[2] =
			// rootPOA.create_request_processing_policy(RequestProcessingPolic)create_thread_policy(ThreadPolicyValue.SINGLE_THREAD_MODEL);
			// Step 3-3: Create a POA by passing the Persistent Policy
			POA persistentPOA = rootPOA.create_POA("childPOA", null,
					persistentPolicy);
			// Step 3-4: Activate PersistentPOA's POAManager, Without this
			// All calls to Persistent Server will hang because POAManager
			// will be in the 'HOLD' state.
			persistentPOA.the_POAManager().activate();
			// ***********************

			// Step 4: Associate the servant with PersistentPOA
			persistentPOA.activate_object(servant);

			// Step 5: Resolve RootNaming context and bind a name for the
			// servant.
			// NOTE: If the Server is persistent in nature then using
			// Persistent
			// Name Service is a good choice. Even if ORBD is restarted the
			// Name
			// Bindings will be intact. To use Persistent Name Service use
			// 'NameService' as the key for resolve_initial_references()
			// when
			// ORBD is running.
			org.omg.CORBA.Object obj = orb
					.resolve_initial_references("NameService");
			NamingContextExt rootContext = NamingContextExtHelper
					.narrow(obj);

			NameComponent[] nc = rootContext.to_name("PermissionTransfer");
			rootContext.rebind(nc, persistentPOA
					.servant_to_reference(servant));

			// Step 6: We are ready to receive client requests
			orb.run();
		} catch (Exception e) {
			System.err.println("Exception in Persistent Server Startup "
					+ e);
		}
	}
	// TODO Auto-generated method stub

}


public class Receiver {

	static final java.util.logging.Logger log = java.util.logging.Logger
			.getLogger("JChains");

	static String applicationName = "PermissionTransfer";
	static String classpath = new File("ia.zip").getAbsolutePath();
	static String name = Receiver.class.getName();
	// static String vmargs = "-Xmx512M -Djava.io.tmpdir=.";
	static String vmargs = "-Xmx512M";
	static String progargs = ""; // new

	// String[]{"-Xmx512M","-Djava.io.tmpdir=."};

	
	public static void main(String args[]) {
		ReceiverStrategy rs = null; 
		System.out.println("*");
		System.out.println(applicationName);
		System.out.println(classpath);
		System.out.println(name);
		System.out.println(vmargs);
		System.out.println(progargs);
		if (args.length > 0) {
			if (args[0].equals("-register")) {
				doRegister(args);
			} else if (args[0].equals("-unregister")) {
				doUnRegister(args);
			} else if (args[0].equals("-test")) {
				doTest(args);
			} else if (args[0].equals("-test2")) {
				doTest2(args);
			} else if (args[0].equals("-simplesocket")) {
				doSocketServerStart(args);
			} else if (args[0].equals("-file")) {
				rs = new FileReceiverStrategy();
			}
		} 
		
		if (rs != null) {
			rs.init(args);
		
		}
	}

	private static void doSocketServerStart(String[] args) {
		PermissionTransferServant pts = new PermissionTransferServant(null);
		pts.init("hudel", new EnvironmentEntry[] {});
		Receiver r = new Receiver();
		SocketServer sserv = new SocketServer(pts, r, 14444);
		sserv.start();

	}

	private static void doTest2(String[] args) {
		try {
			Properties properties = System.getProperties();
			properties.put("org.omg.CORBA.ORBInitialHost", "localhost");
			properties.put("org.omg.CORBA.ORBInitialPort", "1050");
			ORB orb = ORB.init(args, properties);
			org.omg.CORBA.Object obj = orb
					.resolve_initial_references("NameService");
			NamingContextExt rootContext = NamingContextExtHelper.narrow(obj);

			BindingListHolder bl = new BindingListHolder();
			BindingIteratorHolder bi = new BindingIteratorHolder();
			rootContext.list(10, bl, bi);

			System.out.println(bl.value[0].binding_name);

			NameComponent[] nc = rootContext.to_name("PermissionTransfer");
			org.omg.CORBA.Object obj1 = rootContext
					.resolve_str("PermissionTransfer");

		} catch (Exception e) {
			e.printStackTrace();
		}
		System.exit(0);
	}

	private static void doTest(String[] args) {
		try {
			String s = System.getProperty("org.jchains.CNameServiceIOR",
					"corbaloc::127.0.0.1:1050/NameService");
			String fn = System.getProperty("org.jchains.outputfile", System
					.currentTimeMillis()
					+ "out.txt");

			// TODO:filename cleanen!
			System.out.println(s);
			System.out.println(fn);
			ORB orb = ORB.init(new String[] {}, null);
			org.omg.CORBA.Object obj = orb.string_to_object(s);
			NamingContextExt namingcontextext = NamingContextExtHelper
					.narrow(obj);
			System.out.println("nc0:" + namingcontextext);
			org.omg.CORBA.Object obj1 = namingcontextext
					.resolve_str("PermissionTransfer");
			Object pt = PermissionTransferHelper.narrow(obj1);
			System.out.println("pt:" + pt);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.exit(0);
	}

	private static void doRegister(String[] args) {
		String[] newargs = newargs(args);

		int serverId = 0;
		try {

			Properties props = System.getProperties();
			props.put("org.omg.CORBA.ORBClass",
					"com.sun.corba.se.impl.orb.ORBImpl");
			props.put("org.omg.CORBA.ORBInitialHost", "localhost");
			props.put("org.omg.CORBA.ORBInitialPort", "1050");
			// args[0]="-ORBInitialPort="
			ORB orb = (ORB) ORB.init(newargs, props);
			// ORB orb = (ORB) ORB.init(newargs, props);
			// register the server with the repository
			Repository repository = RepositoryHelper
					.narrow(orb
							.resolve_initial_references(ORBConstants.SERVER_REPOSITORY_NAME));

			ServerDef server = new ServerDef(applicationName, name, classpath,
					progargs, vmargs);
			serverId = repository.registerServer(server);

			// activate the server
			Activator activator = ActivatorHelper
					.narrow(orb
							.resolve_initial_references(ORBConstants.SERVER_ACTIVATOR_NAME));
			activator.activate(serverId);
			activator.install(serverId);

			// print success message
			System.out.println(CorbaResourceUtil.getText(
					"servertool.register2", serverId));
		} catch (ServerNotRegistered ex) {
		} catch (ServerAlreadyActive ex) {
		} catch (ServerHeldDown ex) {
			System.out.println(CorbaResourceUtil.getText(
					"servertool.register3", serverId));
		} catch (ServerAlreadyRegistered ex) {
			System.out.println(CorbaResourceUtil.getText(
					"servertool.register4", serverId));
		} catch (BadServerDefinition ex) {
			System.out.println(CorbaResourceUtil.getText("servertool.baddef",
					ex.reason));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		System.exit(0);
	}

	private static String[] newargs(String[] args) {
		String[] newargs = new String[args.length - 1];

		System.arraycopy(args, 1, newargs, 0, newargs.length);

		String s1 = Arrays.toString(newargs);
		String s2 = Arrays.toString(args);
		System.out.println(s1 + ":" + s2);
		return newargs;
	}

	static int getServerIdForAlias(ORB orb, String applicationName)
			throws ServerNotRegistered {
		try {
			Repository rep = RepositoryHelper
					.narrow(orb
							.resolve_initial_references(ORBConstants.SERVER_REPOSITORY_NAME));
			int serverid = rep.getServerID(applicationName);

			return rep.getServerID(applicationName);
		} catch (Exception ex) {
			throw (new ServerNotRegistered());
		}
	}

	private static void doUnRegister(String[] args) {
		String[] newargs = newargs(args);
		try {

			Properties props = System.getProperties();
			// props.put("org.omg.CORBA.ORBClass",
			// "com.sun.corba.se.impl.orb.ORBImpl");
			// props.put("org.omg.CORBA.ORBInitialHost", "localhost");
			props.put("org.omg.CORBA.ORBClass",
					"com.sun.corba.se.impl.orb.ORBImpl");
			props.put("org.omg.CORBA.ORBInitialHost", "localhost");
			props.put("org.omg.CORBA.ORBInitialPort", "1050");
			ORB orb = (ORB) ORB.init(newargs, props);
			int serverId = getServerIdForAlias(orb, applicationName);
			// register the server with the repository

			try {
				Activator activator = ActivatorHelper
						.narrow(orb
								.resolve_initial_references(ORBConstants.SERVER_ACTIVATOR_NAME));
				activator.uninstall(serverId);
			} catch (ServerHeldDown ex) {
			}

			// unregister the server from the repository 
			Repository repository = RepositoryHelper
					.narrow(orb
							.resolve_initial_references(ORBConstants.SERVER_REPOSITORY_NAME));
			repository.unregisterServer(serverId);

			// print success message
			System.out.println(CorbaResourceUtil
					.getText("servertool.unregister2"));
		} catch (ServerNotRegistered ex) {
			System.out.println(CorbaResourceUtil
					.getText("servertool.nosuchserver"));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		System.exit(0);
	}
}
